package com.flying.invest.summary.service;

import java.util.Date;
import java.util.List;

import com.flying.common.annotation.DaoCreate;
import com.flying.common.annotation.DaoQuery;
import com.flying.common.annotation.DaoRemove;
import com.flying.common.annotation.Transaction;
import com.flying.common.util.Codes;
import com.flying.common.util.DateUtils;
import com.flying.common.util.DateUtils.Field;
import com.flying.framework.annotation.MethodInfo;
import com.flying.framework.annotation.Param;
import com.flying.framework.annotation.Service;
import com.flying.framework.context.ServiceContext;
import com.flying.framework.model.ActionResult;
import com.flying.framework.model.ModelFactory;
import com.flying.framework.model.QueryResult;
import com.flying.framework.security.Principal;
import com.flying.framework.service.AbstractService;
import com.flying.invest.invest.TransactionType;
import com.flying.invest.invest.model.InvestmentTransaction.Status;
import com.flying.invest.invest.service.InvestmentTransactionService;
import com.flying.invest.summary.model.SummaryInvestDaily;
import com.flying.invest.summary.model.SummaryInvestDailyExt;

@Service(value="SummaryInvestDailyService", desc="")
public class SummaryInvestDailyService extends AbstractService{
	private InvestmentTransactionService transService;
	public void setInvestmentTransactionService(InvestmentTransactionService s) {
		this.transService = s;
	}
        
	@MethodInfo("新增")
	@DaoCreate(entity=SummaryInvestDaily.ENTITY_NAME)
	public SummaryInvestDaily create(
			@Param(value=SummaryInvestDaily.USER_ID, required=true,	desc="用户ID") Long user_id,
			@Param(value=SummaryInvestDaily.ACCOUNT_ID, required=false,	desc="投资账户ID") Long account_id,
			@Param(value=SummaryInvestDaily.ASSETS_ID, required=false,	desc="投资品种") Long assets_id,
			@Param(value=SummaryInvestDaily.INVEST_ID, required=true,	desc="投资ID") Long invest_id,
			@Param(value=SummaryInvestDaily.STATUS, required=true,	desc="投资ID") Integer status,
			@Param(value=SummaryInvestDaily.NAME, required=false,	desc="名称") String name,
			
			@Param(value=SummaryInvestDaily.SUM_DATE, required=true,	desc="汇总日期") String sum_date,
			@Param(value=SummaryInvestDaily.SUMMARY_DATE, required=true,	desc="汇总日期") Date summary_date,
			@Param(value=SummaryInvestDaily.CURRENCY, required=true,	desc="币种") String currency,
			@Param(value=SummaryInvestDaily.CURRENCY_RATE, required=true,	desc="汇率") Double currency_rate,
			
			@Param(value=SummaryInvestDaily.ACTUAL_MONEY, required=false,	desc="实际投入金额") Double actual_money,
			@Param(value=SummaryInvestDaily.QUANTITY, required=false,	desc="资产数量") Double quantity,
			@Param(value=SummaryInvestDaily.TAX, required=false,	desc="税额") Double tax,
			@Param(value=SummaryInvestDaily.COST, required=false,	desc="成本") Double cost,
			@Param(value=SummaryInvestDaily.COST_PRICE, required=false,	desc="成本价") Double cost_price,
			@Param(value=SummaryInvestDaily.AMOUNT, required=false,	desc="市值") Double amount,
			
			@Param(value=SummaryInvestDaily.LIMIT_RATE, required=false,	desc="限制比例") Double limit_rate,
			@Param(value=SummaryInvestDaily.ACTUALLY_RATE, required=false,	desc="实际比例") Double actual_rate,
			@Param(value=SummaryInvestDaily.PRICE, required=false,	desc="价格") Double price,
			@Param(value=SummaryInvestDaily.PROFIT, required=false,	desc="总收益") Double profit,
			@Param(value=SummaryInvestDaily.PERIOD_PROFIT, required=false,	desc="日收益") Double peroid_profit,

			@Param(value=SummaryInvestDaily.PERIOD_BUY_AMOUNT, required=false,	desc="买入金额") Double period_buy_amount,
			@Param(value=SummaryInvestDaily.PERIOD_BUY_COUNT, required=false,	desc="买入笔数") Integer period_buy_count,
			@Param(value=SummaryInvestDaily.PERIOD_SELL_AMOUNT, required=false,	desc="卖出金额") Double period_sell_amount,
			@Param(value=SummaryInvestDaily.PERIOD_SELL_COUNT, required=false,	desc="卖出笔数") Integer period_sell_count
		) {
		return null;
	}
	
	@Transaction
	public ActionResult createByUserId(
			@Param(value=SummaryInvestDaily.USER_ID, required=true,	desc="用户ID")final Long user_id) {
		List<SummaryInvestDaily> list = this.findSummarySourceByUserId(user_id).getRows();
		
		final Double total_amount = list.stream().mapToDouble(x -> x.getAmount() * x.getCurrencyRate()).sum();
		list.stream().filter(x -> x.getAmount() != null).forEach(x -> {
			try {
				x.setActuallyRate(x.getAmount()*x.getCurrencyRate() / total_amount);
				this.remove(user_id, x.getAccountId(), x.getAssetsId(), x.getInvestId(), x.getSumDate());
				this.create(user_id, x.getAccountId(), x.getAssetsId(), x.getInvestId(), x.getStatus(), x.getName(), 
						x.getSumDate(), x.getSummaryDate(), x.getCurrency(), x.getCurrencyRate(), 
						x.getActualMoney(), x.getQuantity(), x.getTax(), x.getCost(), x.getCostPrice(), x.getAmount(), 
						x.getLimitRate(), x.getActuallyRate(), x.getPrice(), x.getProfit(), x.getPeriodProfit(), 
						x.getPeriodBuyAmount(), x.getPeriodBuyCount(), x.getPeriodSellAmount(), x.getPeriodSellCount());
			} catch (Exception e) {
				System.err.println("SummaryInvestDailyService.createByUserId fail, target " + x +"; Reason :" + e);
			}
		});
		return ModelFactory.create(ActionResult.class, Codes.EFFECT_ROWS, list.size());
	}

	@MethodInfo("删除")
	@DaoRemove(entity=SummaryInvestDaily.ENTITY_NAME)
	public ActionResult remove(
			@Param(value=SummaryInvestDaily.USER_ID, required=true,	desc="用户ID") Long user_id,
			@Param(value=SummaryInvestDaily.ACCOUNT_ID, required=false,	desc="投资账户ID") Long account_id,
			@Param(value=SummaryInvestDaily.ASSETS_ID, required=false,	desc="投资品种") Long assets_id,
			@Param(value=SummaryInvestDaily.INVEST_ID, required=true,	desc="投资ID") Long invest_id,
			@Param(value=SummaryInvestDaily.SUM_DATE, required=true,	desc="汇总日期") String sum_date
		) {
		return null;
	}

	@SuppressWarnings("unchecked")
	@MethodInfo("搜索")
	@DaoQuery(entity=SummaryInvestDaily.ENTITY_NAME, pageable=true, modelClass=SummaryInvestDaily.class, 
		wsql="status < 9", osql="order by sum_date desc, actually_rate desc")
	public QueryResult<SummaryInvestDaily> findAll(
			@Param(value=SummaryInvestDaily.USER_ID, required=false,	desc="用户ID") Long user_id,
			@Param(value=SummaryInvestDaily.INVEST_ID, required=false,	desc="投资ID") Long invest_id,
			@Param(value=SummaryInvestDaily.SUM_DATE, required=false,	desc="汇总日期") String sum_date,
			@Param(value=Codes.PAGE_NUM, 	required=false, desc="分页页号，默认0") int page,
			@Param(value=Codes.PAGE_SIZE, 	required=false, desc="分页大小，默认10") int rows) {
		Principal p = ServiceContext.getContext().getPrincipal();
		if(user_id == null && p != null) {
			user_id = Long.parseLong(p.getId());
		}
		return ModelFactory.create(QueryResult.class, SummaryInvestDaily.USER_ID, user_id);
	}

	@SuppressWarnings("unchecked")
	@MethodInfo("搜索投资项目下的所有统计信息")
	@DaoQuery(entity=SummaryInvestDaily.ENTITY_NAME, pageable=false, modelClass=SummaryInvestDailyExt.class, 
		wsql="assets_id > 0", osql="order by sum_date desc")
	public QueryResult<SummaryInvestDailyExt> findByInvestId(
			@Param(value=SummaryInvestDaily.INVEST_ID, required=true,	desc="投资ID") Long invest_id,
			@Param(value=SummaryInvestDaily.SUM_DATE, required=false,	desc="汇总日期", tag=">") String sum_date) {
		return ModelFactory.create(QueryResult.class, SummaryInvestDaily.SUM_DATE, sum_date);
	}

	@MethodInfo("用于单一投资统计报表")
	public QueryResult<SummaryInvestDailyExt> findSummaryReportByInvestId(
			@Param(value=SummaryInvestDaily.INVEST_ID, required=true,	desc="投资ID") Long invest_id,
			@Param(value=SummaryInvestDaily.SUM_DATE, required=false,	desc="汇总日期", tag=">") String sum_date) {
		final Date date;
		if(sum_date == null) {
			date = DateUtils.add(new Date(), Field.YEAR, -1);
			sum_date = DateUtils.formatDate(date, "yyyy-MM-dd");
		} else {
			date = DateUtils.parseDate(sum_date, "yyyy-MM-dd");
		}
		var trans = this.transService.findAll(null, invest_id, null, null, null, new Integer[Status.SUCCESS.value()], new Date[] {date, new Date()}, null, 0, 10000).getRows();
		var result = this.findByInvestId(invest_id, sum_date);
		var rows = result.getRows();
		rows.stream().forEach(row -> {
			trans.stream().filter(t -> row.getSumDate().equals(DateUtils.formatDate(t.getTransactionFinishTime(), "yyyy-MM-dd")))
			.forEach(t -> {
				if(t.getTransactionType() == TransactionType.BUY.value()) {
					row.setBuyPrice(t.getPrice());
					row.setBuyQuantity(t.getQuantity() + (row.getBuyQuantity() == null?0: row.getBuyQuantity()));
				} else {
					row.setSellPrice(t.getPrice());
					row.setSellQuantity(t.getQuantity() + (row.getSellQuantity() == null?0: row.getSellQuantity()));
				}
			});;
		});
		return result;
	}

	@MethodInfo("搜索")
	@DaoQuery(entity=SummaryInvestDaily.ENTITY_NAME, pageable=false, modelClass=SummaryInvestDaily.class, 
		osql="order by sum_date desc, invest_id")
	public QueryResult<SummaryInvestDaily> findByUserIdAndDate(
			@Param(value=SummaryInvestDaily.USER_ID, required=true,	desc="用户ID") Long user_id,
			@Param(value=SummaryInvestDaily.SUM_DATE, required=true,	desc="汇总日期") String sum_date) {
		return null;
	}

	@MethodInfo("查询")
	@DaoQuery(entity=SummaryInvestDaily.ENTITY_NAME, single=true, throwsNotFoundException=true )
	public SummaryInvestDaily findById(
			@Param(value=SummaryInvestDaily.SUMMARY_ID, required=true,	desc="ID") Long summary_id
		) {
		return null;
	}

	@MethodInfo("搜索投资项目下的所有统计信息")
	@DaoQuery(entity=SummaryInvestDaily.ENTITY_NAME, single=true, modelClass=SummaryInvestDailyExt.class, 
		osql="order by profit desc")
	public SummaryInvestDailyExt findByInvestIdForMaxProfit(
			@Param(value=SummaryInvestDaily.INVEST_ID, required=true,	desc="投资ID") Long invest_id) {
		return null;
	}

	@MethodInfo("查询")
	@DaoQuery(entity=SummaryInvestDaily.ENTITY_NAME, single=true, throwsNotFoundException=false )
	protected SummaryInvestDaily findByInvestIdAndDate(
			@Param(value=SummaryInvestDaily.INVEST_ID, required=true,	desc="投资ID") Long invest_id,
			@Param(value=SummaryInvestDaily.SUM_DATE, required=true,	desc="汇总日期") String sum_date
		) {
		return null;
	}

	//
	@MethodInfo("查询投资数据源，包括投资数据和账户数据")
	@DaoQuery(entity=SummaryInvestDaily.ENTITY_NAME, pageable=false, modelClass=SummaryInvestDaily.class, 
		qsql="select * from v_summary_invest_source t")
	protected QueryResult<SummaryInvestDaily> findSummarySourceByUserId(
			@Param(value=SummaryInvestDaily.USER_ID, required=true,	desc="用户ID") Long user_id) {
		return null;
	}
}